home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / drivers1.zip / DE600.ASM < prev    next >
Assembly Source File  |  1992-01-28  |  45KB  |  2,147 lines

  1. PAGE  ,132
  2.    .286c
  3. version equ     0
  4.  
  5.     include defs.asm        ;SEE ENCLOSED COPYRIGHT MESSAGE
  6.  
  7. ;/* PC/FTP Packet Driver source, conforming to version 1.09 of the spec
  8. ;*  Portions (C) Copyright 1990 D-Link, Inc.
  9. ;*
  10. ;*  Permission is granted to any individual or institution to use, copy,
  11. ;*  modify, or redistribute this software and its documentation provided
  12. ;*  this notice and the copyright notices are retained.  This software may
  13. ;*  not be distributed for profit, either in original form or in derivative
  14. ;*  works.  D-Link, inc. makes no representations about the suitability
  15. ;*  of this software for any purpose.  D-LINK GIVES NO WARRANTY,
  16. ;*  EITHER EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION
  17. ;*  PROVIDED, INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY
  18. ;*  AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  19. ;*/
  20.  
  21. BIT0            EQU     01H
  22. BIT1            EQU     02H
  23. BIT2            EQU     04H
  24. BIT3            EQU     08H
  25. BIT4            EQU     10H
  26. BIT5            EQU     20H
  27. BIT6            EQU     40H
  28. BIT7            EQU     80H
  29.  
  30. code    segment byte public
  31.     assume  cs:code, ds:code
  32.  
  33. ; DE-600's I/O port Table
  34. DAT             equ     0
  35. STAT            equ     1
  36. CMD             equ     2
  37.  
  38. ; DE-600's DATA port Command
  39. WRITE           equ     0004h   ;write memory
  40. READ            equ     0104h   ;read  memory
  41. STATUS          equ     0204h   ;read  status register
  42. COMMAND         equ     0304h   ;write command register
  43. NUL_CMD         equ     0ch     ;null command
  44. RX_LEN          equ     0504h   ;read  Rx packet length
  45. TX_ADR          equ     0604h   ;write Tx address
  46. RW_ADR          equ     0704h   ;write memory address
  47.  
  48. ;< COMMAND   bits 7-0 >
  49. RXEN            equ     08h    ; bit 3
  50. TXEN            equ     04h    ; bit 2
  51. LOOPBACK        equ     0Ch    ; RXEN=1, TXEN=1
  52. RX_NONE         equ     00h    ; M1=0, M0=0 (bit 1,0)
  53. RX_ALL          equ     01h    ; M1=0, M0=1
  54. RX_BP           equ     02h    ; M1=1, M0=0
  55. RX_MBP          equ     03h    ; M1=1, M0=1
  56. RESET           equ     80h    ; set bit 7 high
  57. STOP_RESET      equ     00h    ; set bit 7 low
  58. ;  bit 6   -- IRQ inverse
  59. ;  bit 5,4 -- Rx Page Number  ( RA12=1, RA11=0 or 1 )
  60.  
  61. ;< TX_ADR   bit 7, bit 4 >
  62. ;  bit 7   -- Tx Page Number  ( TA11=0 or 1 )
  63. ;  bit 4   -- Tx Page Number  ( TA12=0 )
  64. PAGE0           equ     00h
  65. PAGE1           equ     08h
  66. PAGE2           equ     10h
  67. PAGE3           equ     18h
  68.  
  69. ;< RW_ADR   bit 7, bit 5,4 >
  70. ;  bit 7   -- RW Page Number  ( H11 =? )
  71. ;  bit 4   -- RW Page Number  ( H12 =? )
  72. ;  bit 5   -- Address Maping  ( HA13=0 => Memory, HA13=1 => Node Number )
  73. HA13            equ     020h
  74.  
  75. ; DE-600's CMD port Command
  76. SLT_NIC         equ     004h  ;select Network Interface Card
  77. SLT_PRN         equ     01Ch  ;select Printer
  78. NML_PRN         equ     0ECh  ;normal Printer situation
  79. IRQEN           equ     010h  ;enable IRQ line
  80.  
  81. ; DE-600's STAT port bits 7-4
  82. RXBUSY          equ     80h
  83. GOOD            equ     40h
  84. RESET_FLAG      equ     20h
  85. T16             equ     10h
  86. TXBUSY          equ     08h
  87.  
  88. BFRSIZ          equ     2048    ;number of bytes in a buffer
  89. PRNTABADD       equ     408h    ;DOS printer table address
  90. RX_MIN_LEN      equ     18      ;= EADDR_LEN + EADDR_LEN + TYPE_LEN + CRC
  91.  
  92. write_sub_delay    macro    reg
  93.     mov     al,reg            ;output the low nibble.
  94.     shl     al,cl            ;cl must be four.
  95.     or      al,ch
  96.     xor     al,08h            ;raise the write line.
  97.     out     dx,al
  98.     call    delay
  99.  
  100.     xor     al,08h            ;lower the write line
  101.     out     dx,al
  102.     call    delay
  103.  
  104.     mov     al,reg            ;output the high nibble.
  105.     and     al,not 0fh        ;get us some zero bits.
  106.     or      al,ch
  107.     out     dx,al            ;(write line is low).
  108.     call    delay
  109.  
  110.     xor     al,08h            ;raise the write line.
  111.     out     dx,al
  112.     endm
  113.  
  114. write_sub_fast    macro    reg
  115.     mov     al,reg            ;output the low nibble.
  116.     shl     al,cl            ;cl must be four.
  117.     or      al,ch
  118.     out     dx,al
  119.  
  120.     mov     al,reg            ;output the high nibble.
  121.     and     al,not 0fh        ;get us some zero bits.
  122.     or      al,ch
  123.     xor     al,08h            ;raise the write line.
  124.     out     dx,al            ;(write line is low).
  125.     endm
  126.  
  127. write_sub_slow    macro    reg
  128.     mov     al,reg            ;output the low nibble.
  129.     shl     al,cl            ;cl must be four.
  130.     or      al,ch
  131.     out     dx,al
  132.     call    delay
  133.  
  134.     mov     al,reg            ;output the high nibble.
  135.     and     al,not 0fh        ;get us some zero bits.
  136.     or      al,ch
  137.     xor     al,08h            ;raise the write line.
  138.     out     dx,al            ;(write line is low).
  139.     endm
  140.  
  141. read_sub_fast    macro    reg
  142.     setport DAT
  143.     mov     al,ch
  144.     out     dx,al
  145.     pause
  146.  
  147.     setport STAT
  148.     in      al,dx
  149.     mov     reg,al
  150.     setport DAT
  151.     mov     al,ch
  152.     xor     al,08h
  153.     out     dx,al
  154.     pause
  155.  
  156.     setport STAT
  157.     in      al,dx
  158.     shr     reg,cl
  159.     and     al,0f0h
  160.     or      reg,al
  161.     endm
  162.  
  163.  
  164. read_sub_slow    macro    reg
  165.     setport DAT
  166.     mov     al,ch
  167.     out     dx,al
  168.     call    delay
  169.  
  170.     setport STAT
  171.     in      al,dx
  172.     mov     reg,al
  173.     setport DAT
  174.     mov     al,ch
  175.     xor     al,08h
  176.     out     dx,al
  177.     call    delay
  178.  
  179.     setport STAT
  180.     in      al,dx
  181.     shr     reg,cl
  182.     and     al,0f0h
  183.     or      reg,al
  184.     endm
  185.  
  186.  
  187. read_sub_delay    macro    reg, first
  188.     setport DAT
  189.     mov     al,ch
  190.   if first
  191.     xor     al,08h
  192.   endif
  193.     out     dx,al
  194.     call    delay
  195.  
  196.   if first
  197.     xor     al,08h
  198.     out     dx,al
  199.     call    delay
  200.   endif
  201.  
  202.     setport STAT
  203.     in      al,dx
  204.     mov     reg,al
  205.     setport DAT
  206.     mov     al,ch
  207.     xor     al,08h
  208.     out     dx,al
  209.     call    delay
  210.  
  211.     setport STAT
  212.     in      al,dx
  213.     shr     reg,cl
  214.     and     al,0f0h
  215.     or      reg,al
  216.     endm
  217.  
  218.  
  219. pause    macro
  220.     jmp    $+2
  221.     endm
  222.  
  223.     public  int_no
  224. int_no          db      7,0,0,0         ; IRQ interrupt number
  225. io_addr         dw      03bch,0         ; I/O address for card (jumpers)
  226.  
  227.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  228. driver_class    db      BLUEBOOK, IEEE8023, 0 ;from the packet spec
  229. driver_type     db      31              ;from the packet spec
  230. driver_name     db      'DE600',0      ;name of the driver
  231. driver_function    db    2
  232. parameter_list    label    byte
  233.     db    1    ;major rev of packet driver
  234.     db    9    ;minor rev of packet driver
  235.     db    14    ;length of parameter list
  236.     db    EADDR_LEN    ;length of MAC-layer address
  237.     dw    GIANT    ;MTU, including MAC headers
  238.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  239.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  240.     dw    0    ;(# of successive xmits) - 1
  241. int_num    dw    0    ;Interrupt # to hook for post-EOI
  242.             ;processing, 0 == none,
  243.  
  244.     public    rcv_modes
  245. rcv_modes    dw    7        ;number of receive modes in our table.
  246.         dw    0               ;There is no mode zero
  247.         dw    rcv_mode_1
  248.         dw    0
  249.         dw    rcv_mode_3
  250.         dw    0
  251.         dw    rcv_mode_5
  252.         dw    rcv_mode_6
  253.  
  254. CurTxPage       db      08h             ;the BL value when OUT DATA,TX_ADR
  255. CurRxPage       db      20h             ;the BL value when OUT DATA,COMMAND
  256. TxStartAdd      dw      ?
  257. RxStartAdd      dw      ?
  258. InitRxTxReg     dw      ?
  259. RxPktLen        dw      ?
  260. TxPktLen        dw      ?
  261. Mode_RxPg       db      ?
  262. Mode            db      RX_BP
  263. IRQinverse      db      0               ; = 40h for XT printer adapter
  264. NICstatus       db      0
  265. In_ISR          db      0
  266. In_Tx           db      0
  267. printer         dw      408h
  268. PS2             db      0
  269.  
  270. our_type        dw      ?
  271. our_address     db      EADDR_LEN + EADDR_LEN dup(0) ;temporarily hold our address
  272.  
  273.  
  274.     public    as_send_pkt
  275. ; The Asynchronous Transmit Packet routine.
  276. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  277. ;   interrupts possibly enabled.
  278. ; Exit with nc if ok, or else cy if error, dh set to error number.
  279. ;   es:di and interrupt enable flag preserved on exit.
  280. as_send_pkt:
  281.     ret
  282.  
  283.     public    drop_pkt
  284. ; Drop a packet from the queue.
  285. ; Enter with es:di -> iocb.
  286. drop_pkt:
  287.     assume    ds:nothing
  288.     ret
  289.  
  290.     public    xmit
  291. ; Process a transmit interrupt with the least possible latency to achieve
  292. ;   back-to-back packet transmissions.
  293. ; May only use ax and dx.
  294. xmit:
  295.     assume    ds:nothing
  296.     ret
  297.  
  298.  
  299.     public  send_pkt
  300. send_pkt:
  301. ;enter with ds:si -> packet, cx = packet length.
  302. ;exit with nc if ok, or else cy if error, dh set to error number.
  303.     assume  ds:nothing
  304. ;select DE-600
  305.     mov     al,SLT_NIC
  306. ;*** CMD sub ***
  307.     loadport
  308.     setport CMD
  309.     out     dx,al
  310. ;*** End CMD sub ***
  311.     mov     In_Tx,1
  312.     call    delay
  313.  
  314.     cmp     cx,RUNT         ; minimum length for Ether
  315.     jae     LengthOK
  316.     mov     cx,RUNT         ; make sure size at least RUNT
  317. LengthOK:
  318.     inc     cx
  319.     and     cx,not 1
  320.  
  321.     mov     di,cx
  322. ;change Tx page to another free buffer
  323.     xor     CurTxPage,08h
  324.  
  325.     mov     bx,offset send_pkt_pointer
  326.     jmp     cs:[bx]
  327.  
  328. send_pkt_pointer        dw      offset send_pkt0
  329.  
  330. send_pkt0:
  331. ;set Tx Pointer for moving packet
  332.     mov     ax,BFRSIZ
  333.     sub     ax,cx           ;AX = the pointer to TX
  334.     or      ah,CurTxPage
  335.     mov     TxStartAdd,ax   ;save Current Tx Packet Start Address
  336.     mov     bx,ax           ;write memory address
  337.     mov     cx,RW_ADR
  338.     setport DAT
  339.     write_sub_fast    bl
  340.     write_sub_fast    bh
  341.     cld
  342.     mov     cx,WRITE        ;write packet into memory
  343.     mov     ah,ch
  344.     xor     ah,08h
  345. write_mem:
  346.     lodsb
  347.     mov     bl,al
  348.     shl     al,cl
  349.     or      al,ch
  350.     out     dx,al
  351.  
  352.     mov     al,bl
  353.     and     al,0f0h
  354.     or      al,ah
  355.     dec     di
  356.     out     dx,al
  357.     jnz     write_mem
  358.  
  359.     mov     cx,4000h
  360.     setport STAT
  361. wait_Tx_idle:
  362.     in      al,dx
  363.     test    al,TXBUSY       ; Is the previous Tx successful ?
  364.     jz      command_to_Tx   ; Yes, TXBUSY is low. Then could Tx next packet.
  365.     loop    wait_Tx_idle
  366.  
  367. command_to_Tx:
  368. ;set Tx Pointer at beginning of packet
  369.     mov     bx,TxStartAdd
  370.     mov     cx,TX_ADR
  371.     loadport
  372.     setport DAT
  373.     write_sub_fast    bl
  374.     write_sub_fast    bh
  375.  
  376. ;Enable interrupt and start Tx
  377.     mov     bl,Mode_RxPg
  378.     mov     cx,COMMAND
  379.     write_sub_fast    bl
  380.     or      bl,TXEN
  381.     write_sub_fast    bl
  382.  
  383. Exit_Send_Packet:
  384.     mov     In_Tx,0
  385.  
  386.     cmp     In_ISR,0
  387.     jne     using_NIC_now
  388.     mov     al,SLT_PRN
  389.     loadport
  390.     setport CMD
  391.     out     dx,al
  392.  
  393.     cmp     PS2,0
  394.     jnz     using_NIC_now
  395.     setport STAT
  396.     in      al,dx
  397.     and     al,40h
  398.     xor     al,IRQinverse
  399.     jz      using_NIC_now
  400.     call    trigger_int
  401. using_NIC_now:
  402.     clc
  403.     ret
  404.  
  405.  
  406. send_pkt1:
  407. ;set Tx Pointer for moving packet
  408.     mov     ax,BFRSIZ
  409.     sub     ax,cx           ;AX = the pointer to TX
  410.     or      ah,CurTxPage
  411.     mov     TxStartAdd,ax   ;save Current Tx Packet Start Address
  412.     mov     bx,ax           ;write memory address
  413.     mov     cx,RW_ADR
  414.     loadport
  415.     setport DAT
  416.     write_sub_slow    bl
  417.     call    delay
  418.     write_sub_slow    bh
  419.  
  420.     cld
  421.     mov     cx,WRITE        ;write packet into memory
  422.     mov     ah,ch
  423.     xor     ah,08h
  424. write_mem1:
  425.     lodsb
  426.     mov     bl,al
  427.     shl     al,cl
  428.     or      al,ch
  429.     out     dx,al
  430.     call    delay
  431.  
  432.     mov     al,bl
  433.     and     al,0f0h
  434.     or      al,ah
  435.     dec     di
  436.     out     dx,al
  437.     call    delay
  438.     jnz     write_mem1
  439.  
  440.     mov     cx,4000h
  441.     setport STAT
  442. wait_Tx_idle1:
  443.     in      al,dx
  444.     test    al,TXBUSY       ; Is the previous Tx successful ?
  445.     jz      command_to_Tx1  ; Yes, TXBUSY is low. Then could Tx next packet.
  446.     loop    wait_Tx_idle1
  447.  
  448. command_to_Tx1:
  449. ;set Tx Pointer at beginning of packet
  450.     mov     bx,TxStartAdd
  451.     mov     cx,TX_ADR
  452.     loadport
  453.     setport DAT
  454.     write_sub_slow    bl
  455.     call    delay
  456.     write_sub_slow    bh
  457.     call    delay
  458.  
  459. ;Enable interrupt and start Tx
  460.     mov     bl,Mode_RxPg
  461.     mov     cx,COMMAND
  462.     write_sub_slow    bl
  463.     call    delay
  464.     or      bl,TXEN
  465.     write_sub_slow    bl
  466.     jmp     Exit_Send_Packet
  467.  
  468.  
  469. send_pkt2:
  470. ;set Tx Pointer for moving packet
  471.     mov     ax,BFRSIZ
  472.     sub     ax,cx           ;AX = the pointer to TX
  473.     or      ah,CurTxPage
  474.     mov     TxStartAdd,ax   ;save Current Tx Packet Start Address
  475.     mov     bx,ax           ;write memory address
  476.     mov     cx,RW_ADR
  477.     loadport
  478.     setport DAT
  479.     write_sub_delay    bl
  480.     call    delay
  481.     write_sub_delay    bh
  482.     cld
  483.     mov     cx,WRITE        ;write packet into memory
  484. write_mem2:
  485.     lodsb
  486.     mov     bl,al            ;except for this line,
  487.     shl     al,cl            ;  it's write_sub_delay
  488.     or      al,ch
  489.     xor     al,08h
  490.     out     dx,al
  491.     call    delay
  492.  
  493.     xor     al,08h
  494.     out     dx,al
  495.     call    delay
  496.  
  497.     mov     al,bl
  498.     and     al,0f0h
  499.     or      al,ch
  500.     out     dx,al
  501.     call    delay
  502.  
  503.     xor     al,08h
  504.     out     dx,al
  505.     call    delay
  506.     dec     di
  507.     jnz     write_mem2
  508.  
  509.     mov     cx,4000h
  510.     setport STAT
  511. wait_Tx_idle2:
  512.     in      al,dx
  513.     test    al,TXBUSY       ; Is the previous Tx successful ?
  514.     jz      command_to_Tx2  ; Yes, TXBUSY is low. Then could Tx next packet.
  515.     loop    wait_Tx_idle2
  516.  
  517. command_to_Tx2:
  518. ;set Tx Pointer at beginning of packet
  519.     mov     bx,TxStartAdd
  520.     mov     cx,TX_ADR
  521.     loadport
  522.     setport DAT
  523.     write_sub_delay    bl
  524.     call    delay
  525.     write_sub_delay    bh
  526.     call    delay
  527.  
  528. ;Enable interrupt and start Tx
  529.     mov     bl,Mode_RxPg
  530.     mov     cx,COMMAND
  531.     write_sub_delay    bl
  532.     call    delay
  533.     or      bl,TXEN
  534.     write_sub_delay    bl
  535.     jmp     Exit_Send_Packet
  536.  
  537.  
  538. trigger_int:
  539.     mov     al,SLT_NIC
  540.     call    CMD_sub
  541.  
  542.     mov     bl,Mode_RxPg
  543.     xor     bl,BIT6
  544.     mov     cx,COMMAND
  545.     call    Write_sub
  546.  
  547.     mov     al,SLT_PRN
  548.     call    CMD_sub
  549.  
  550.     call    delay
  551.     call    delay
  552.  
  553.     mov     al,SLT_NIC
  554.     call    CMD_sub
  555.  
  556.     mov     bl,Mode_RxPg
  557.     mov     cx,COMMAND
  558.     call    Write_sub
  559.     ret
  560.  
  561.  
  562.     public  get_address
  563. get_address:
  564. ;get the address of the interface.
  565. ;enter with es:di -> place to get the address, cx = size of address buffer.
  566.     assume  ds:code
  567.     cmp     cx,EADDR_LEN            ;make sure that we have enough room.
  568.     jb      cant_get_address
  569.  
  570. ;select DE-600
  571.     cld
  572.     mov     si,offset our_address
  573.     rep     movsb
  574.     mov     cx,EADDR_LEN
  575.     clc
  576.     ret
  577. cant_get_address:
  578.     stc
  579.     ret
  580.  
  581.  
  582. rcv_mode_1:
  583.     mov     cl,RX_NONE
  584.     jmp     short set_RXCR
  585. rcv_mode_3:
  586.     mov     cl,RX_BP
  587.     jmp     short set_RxCR
  588. rcv_mode_5:
  589.     mov     cl,RX_MBP
  590.     jmp     short set_RxCR
  591. rcv_mode_6:
  592.     mov     cl,RX_ALL
  593. set_RxCR:
  594.     mov     Mode,cl
  595.     mov     bl,cl
  596.     or      bl,CurRxPage            ; Add original Rx Page
  597.     mov     Mode_RxPg,bl            ; Save Rx Mode & Rx Page
  598. ;select DE-600
  599.     loadport
  600.     setport CMD
  601.     in      al,dx
  602.     pause
  603.     test    al,BIT4
  604.     jz      in_IC_mode
  605. ;not active, we have to put a wrapper around it.
  606.     mov     al,int_no
  607.     call    maskint
  608.  
  609.     mov     al,SLT_NIC        ;turn on the NIC.
  610.     call    CMD_sub
  611.     call    in_IC_mode        ;now we're in the right mode.
  612.     mov     al,SLT_PRN        ;turn on the PRN.
  613.     call    CMD_sub
  614.  
  615.     mov     al,int_no
  616.     call    unmaskint
  617.     ret
  618.  
  619. in_IC_mode:
  620.     mov     cx,COMMAND              ; Set new Rx Mode
  621.     call    Write_sub
  622.     ret
  623.  
  624.  
  625.     extrn   maskint : near
  626.     extrn   unmaskint : near
  627.  
  628.     public  set_address
  629. set_address:
  630. ;Set Ethernet address on controller
  631. ;enter with ds:si -> Ethernet address, CX = length of address.
  632. ;exit with nc if okay, or cy, dh=error if any errors.
  633. ;
  634.     assume  ds:nothing
  635.     cmp     cx,EADDR_LEN            ;make sure that we have enough room.
  636.     je      can_set_address
  637.     mov     dh,BAD_ADDRESS
  638.     stc
  639.     jmp     set_address_none
  640.  
  641. ;select DE-600
  642. can_set_address:
  643.     loadport
  644.     setport CMD
  645.     in      al,dx
  646.     push    ax
  647.     test    al,BIT4
  648.     jz      IC_mode
  649.  
  650.     mov     al,int_no
  651.     call    maskint
  652.     mov     al,SLT_NIC
  653.     call    CMD_sub
  654. IC_mode:
  655.     mov     cx,RW_ADR
  656.     xor     bl,bl
  657.     call    Write_sub
  658.     or      bl,HA13
  659.     call    Write_sub
  660.  
  661.     cld
  662.     mov     bp,cs
  663.     mov     es,bp
  664.     mov     bp,si
  665.  
  666.     mov     cx,EADDR_LEN
  667.     mov     di,offset our_address
  668.     rep     movsb
  669.  
  670.     mov     si,bp
  671.     mov     di,EADDR_LEN
  672.     mov     cx,WRITE
  673. set_our_address:
  674.     lodsb
  675.     mov     bl,al
  676.     call    Write_sub
  677.     dec     di
  678.     jnz     set_our_address
  679.  
  680.     pop     ax
  681.     test    al,BIT4
  682.     jz      IC_mode1
  683.  
  684.     mov     al,SLT_PRN
  685.     call    CMD_sub
  686.     mov     al,int_no
  687.     call    unmaskint
  688. IC_mode1:
  689.     clc
  690. set_address_none:
  691.     push    cs
  692.     pop     ds
  693.     assume  ds:code
  694.     ret
  695.  
  696.  
  697.     public    set_multicast_list
  698. set_multicast_list:
  699. ;enter with ds:si ->list of multicast addresses, cx = number of addresses.
  700. ;return nc if we set all of them, or cy,dh=error if we didn't.
  701.     mov    dh,NO_MULTICAST
  702.     stc
  703.     ret
  704.  
  705.  
  706.     public    terminate
  707. terminate:
  708.     ret
  709.  
  710.  
  711.     public  reset_interface
  712. reset_interface:
  713.     mov     al,int_no
  714.     call    maskint
  715. ;select DE-600
  716.  
  717.     mov     al,SLT_NIC
  718.     call    CMD_sub
  719.  
  720. ; Pulse IE_RESET
  721.     mov     bl,RESET
  722.     mov     cx,COMMAND
  723.     call    Write_sub
  724.     mov     bl,STOP_RESET
  725.     call    Write_sub
  726.  
  727. ; Initialize Rx buffer pointer, and start receive
  728.     mov     bl,Mode_RxPg
  729.     mov     cx,COMMAND
  730.     call    Write_sub
  731.     or      bl,RXEN
  732.     call    Write_sub
  733.  
  734. ; Enable Printer Adapter IRQ line
  735.     mov     al,SLT_PRN
  736.     call    CMD_sub
  737.  
  738.     mov     al,int_no
  739.     call    unmaskint
  740.     ret
  741.  
  742.  
  743.     assume  ds:nothing
  744. Write_sub:
  745.     loadport
  746.     setport DAT
  747.     write_sub_delay    bl
  748.     ret
  749.  
  750. Read_sub:
  751.     loadport
  752.     setport DAT
  753.     mov     al,ch
  754.     xor     al,08h
  755.     out     dx,al
  756.     call    delay
  757.  
  758.     xor     al,08h
  759.     out     dx,al
  760.     call    delay
  761.  
  762.     setport STAT
  763.     in      al,dx
  764.     mov     bl,al
  765.     test    ch,BIT1
  766.     jz      not_READ_STATUS
  767.     dec     dx
  768.     mov     al,NUL_CMD
  769.     xor     al,08h
  770.     out     dx,al
  771.     call    delay
  772.  
  773.     xor     al,08h
  774.     out     dx,al
  775.     jmp     short End_read
  776. not_READ_STATUS:
  777.     setport DAT
  778.     mov     al,ch
  779.     xor     al,08h
  780.     out     dx,al
  781.     call    delay
  782.  
  783.     setport STAT
  784.     in      al,dx
  785.     shr     bl,cl
  786.     and     al,0f0h
  787.     or      bl,al
  788. End_read:
  789.     ret
  790.  
  791. CMD_sub:
  792.     loadport
  793.     setport CMD
  794.     out     dx,al
  795.     ret
  796.  
  797. delay:
  798.     nop     ; pointer 0
  799.     nop     ;         1
  800.     nop     ;         2
  801.     nop     ;         3
  802.     nop     ;         4
  803.     nop     ;         5
  804.     nop     ;         6
  805.     nop     ;         7
  806.     nop     ;         8
  807.     nop     ;         9
  808.     ret
  809.  
  810. ;called when we want to determine what to do with a received packet.
  811. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  812.     extrn   recv_find: near
  813.  
  814. ;called after we have copied the packet into the buffer.
  815. ;enter with ds:si ->the packet, cx = length of the packet.
  816.     extrn   recv_copy: near
  817.  
  818.     extrn   count_in_err: near
  819.     extrn   count_out_err: near
  820.  
  821. recv_pointer    dw      offset recv0
  822.  
  823.     public  recv
  824. recv:
  825. ;called from the recv isr.  All registers have been saved, and ds=cs.
  826. ;Upon exit, the interrupt will be acknowledged.
  827.     assume  ds:code
  828. ;select DE-600
  829.     mov     al,SLT_NIC
  830. ;*** CMD sub ***
  831.     loadport
  832.     setport CMD
  833.     out     dx,al
  834. ;*** End CMD sub ***
  835. ;set watch dog
  836.     mov     In_ISR,1
  837.     call    delay
  838.  
  839. ;Check the interrupt source, Rx or Tx ?
  840.     mov     cx,STATUS               ; Read NIC Status Register
  841. ;*** Read sub ***
  842.     setport DAT
  843.     mov     al,ch
  844.     out     dx,al
  845.     pause
  846.     setport STAT
  847.     in      al,dx
  848. ;*** End Read sub ***
  849.  
  850.     jmp    recv_pointer
  851.  
  852. recv0:
  853.     mov     NICstatus,al            ; save NIC status
  854.     setport DAT
  855.     test    al,GOOD                 ; Is Rx generating interrupt ?
  856.     mov     al,NUL_CMD
  857.     out     dx,al
  858.     jnz     Rx_Good_Pkt             ; Yes, take care of this situation.
  859.     mov     al,NICstatus
  860.     test    al,RXBUSY
  861.     jz      Enable_Rx
  862.     jmp     CheckTx
  863.  
  864. Enable_Rx:
  865. ;change Rx page & enable NIC to Rx
  866.     mov     bl,Mode_RxPg
  867.     mov     cx,COMMAND
  868.     setport DAT
  869.     write_sub_fast    bl
  870.     or      bl,RXEN
  871.     write_sub_fast    bl
  872.     jmp     CheckTx
  873.  
  874. Rx_Good_Pkt:
  875. ;Put it on the receive queue
  876.     mov     cx,RX_LEN               ; read Rx Packet Length
  877.     loadport
  878.     read_sub_fast    bl
  879.     read_sub_fast    bh
  880.  
  881.     sub     bx,4                    ;subtrate 4 CRC Byte Count
  882.     mov     RxPktLen,bx             ;save Rx Packet Length
  883.  
  884. ;change Rx page & enable NIC to Rx
  885.     xor     Mode_RxPg,10h
  886.     mov     bl,Mode_RxPg
  887.     mov     cx,COMMAND
  888.     setport DAT
  889.     write_sub_fast    bl
  890.     or      bl,RXEN
  891.     write_sub_fast    bl
  892.     xor     bx,bx
  893.     mov     bh,CurRxPage            ;BL = Current Rx Page
  894.     xor     CurRxPage,10h           ;change to next page for Rx
  895.     shr     bx,1                    ;shift BX to real memory address
  896.     mov     RxStartAdd,bx           ;save just Rx Packet Start Address
  897.  
  898.     add     bx,EADDR_LEN+EADDR_LEN  ;seek to the TYPE word
  899.     mov     cx,RW_ADR
  900.     write_sub_fast    bl
  901.     write_sub_fast    bh
  902.     pause
  903.     mov     cx,READ                 ;read the TYPE word
  904.     read_sub_fast    bl
  905.     read_sub_fast    bh
  906.  
  907.     mov     our_type,bx             ;save the TYPE word
  908.  
  909.     mov     ax,ds
  910.     mov     es,ax
  911.     mov     di,offset our_type
  912.     mov     cx,RxPktLen
  913.  
  914.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  915.     mov    ax, es:[di]
  916.     xchg    ah, al
  917.     cmp     ax, 1500
  918.     ja    BlueBookPacket
  919.     inc    di            ;set di to 802.2 header
  920.     inc    di
  921.     mov    dl, IEEE8023
  922. BlueBookPacket:
  923.     call    recv_find               ;request a Rx buffer to store Rx data
  924.  
  925.     mov     ax,es                   ;is this pointer null?
  926.     or      ax,di
  927.     jnz     find_buffer
  928.     jmp     short CheckTx                 ;yes - just free the frame.
  929. find_buffer:
  930.     push    es
  931.     push    di                   ;remember where the buffer pointer is.
  932.     assume  ds:nothing
  933.     mov     bx,RxStartAdd
  934.     mov     cx,RW_ADR
  935.     loadport
  936.     setport DAT
  937.     write_sub_fast    bl
  938.     write_sub_fast    bh
  939.  
  940.     cld
  941.     mov     bp,RxPktLen             ;CX = the byte count of Rx Packet
  942.     setport STAT
  943.     mov     cx,READ
  944.     mov     ah,ch
  945.     xor     ah,08h
  946. read_mem:
  947.     setport    DAT
  948.     mov     al,ch            ;output our read request.
  949.     out     dx,al
  950.     pause
  951.  
  952.     setport    STAT
  953.     in      al,dx            ;input four bits into bl.
  954.     mov     bl,al
  955.     setport    DAT            ;now output the inverse read request.
  956.     mov     al,ah
  957.     out     dx,al
  958.     pause
  959.  
  960.     setport    STAT
  961.     in      al,dx            ;input the high four bits.
  962.     shr     bl,cl
  963.     and     al,0f0h
  964.     or      al,bl            ;combine the two nibbles.
  965.     stosb
  966.     dec     bp
  967.     jnz     read_mem
  968.  
  969. RxCopy_CheckTx:
  970.     pop     si
  971.     pop     ds
  972.     mov     cx,RxPktLen
  973.  
  974.     call    recv_copy               ;tell them that we copied it.
  975.  
  976.     mov     ax,cs                   ;restore our ds.
  977.     mov     ds,ax
  978.     assume  ds:code
  979.  
  980. CheckTx:
  981.     test    NICstatus,T16           ; Is pending a Tx Packet ?
  982.     jz      return                  ; No, then return.
  983.                                     ; Yes, send this packet.
  984. ;set Tx Pointer at beginning of packet
  985.     mov     bx,TxStartAdd
  986.     mov     cx,TX_ADR
  987.     call    Write_sub
  988.     xchg    bh,bl
  989.     call    Write_sub
  990.  
  991. ;Enable interrupt and start Tx
  992.     mov     bl,Mode_RxPg
  993.     mov     cx,COMMAND
  994.     call    Write_sub
  995.     or      bl,TXEN
  996.     call    Write_sub
  997. return:
  998.     mov     al,SLT_PRN
  999. ;*** CMD sub ***
  1000.     loadport
  1001.     setport CMD
  1002.     out     dx,al
  1003. ;*** End CMD sub ***
  1004.  
  1005.     cmp     PS2,0
  1006.     jnz     Rx_another_pkt
  1007.     setport STAT
  1008.     in      al,dx
  1009.     and     al,40h
  1010.     xor     al,IRQinverse
  1011.     jz      Rx_another_pkt
  1012.     call    trigger_int
  1013. Rx_another_pkt:
  1014.     mov     In_ISR,0
  1015.     ret
  1016.  
  1017.  
  1018. recv1:
  1019.     assume  ds:code
  1020.     mov     NICstatus,al            ; save NIC status
  1021.     loadport
  1022.     setport DAT
  1023.     test    al,GOOD                 ; Is Rx generating interrupt ?
  1024.     mov     al,NUL_CMD
  1025.     out     dx,al
  1026.     jnz     Rx_Good_Pkt1             ; Yes, take care of this situation.
  1027.     mov     al,NICstatus
  1028.     test    al,RXBUSY
  1029.     jz      Enable_Rx1
  1030.     jmp     CheckTx                 ; No, go to check Tx.
  1031.  
  1032. Enable_Rx1:
  1033. ;change Rx page & enable NIC to Rx
  1034.     mov     bl,Mode_RxPg
  1035.     mov     cx,COMMAND
  1036.     setport DAT
  1037.     write_sub_slow    bl
  1038.     call    delay
  1039.     or      bl,RXEN
  1040.     write_sub_slow    bl
  1041.     jmp     CheckTx
  1042.  
  1043. Rx_Good_Pkt1:
  1044. ;Put it on the receive queue
  1045.     mov     cx,RX_LEN               ; read Rx Packet Length
  1046.     loadport
  1047.     read_sub_slow    bl
  1048.     read_sub_slow    bh
  1049.  
  1050.     sub     bx,4                    ;subtrate 4 CRC Byte Count
  1051.     mov     RxPktLen,bx             ;save Rx Packet Length
  1052.  
  1053. ;change Rx page & enable NIC to Rx
  1054.     xor     Mode_RxPg,10h
  1055.     mov     bl,Mode_RxPg
  1056.     mov     cx,COMMAND
  1057.     setport DAT
  1058.     write_sub_slow    bl
  1059.     call    delay
  1060.     or      bl,RXEN
  1061.     write_sub_slow    bl
  1062.     call    delay
  1063.     xor     bx,bx
  1064.     mov     bh,CurRxPage            ;BL = Current Rx Page
  1065.     xor     CurRxPage,10h           ;change to next page for Rx
  1066.     shr     bx,1                    ;shift BX to real memory address
  1067.     mov     RxStartAdd,bx           ;save just Rx Packet Start Address
  1068.  
  1069.     add     bx,EADDR_LEN+EADDR_LEN  ;seek to the TYPE word
  1070.     mov     cx,RW_ADR
  1071.     write_sub_slow    bl
  1072.     call    delay
  1073.     write_sub_slow    bh
  1074.     call    delay
  1075.     mov     cx,READ                 ;read the TYPE word
  1076.  
  1077.     read_sub_slow    bl
  1078.     read_sub_slow    bh
  1079.  
  1080.     mov     our_type,bx             ;save the TYPE word
  1081.  
  1082.     mov     ax,ds
  1083.     mov     es,ax
  1084.     mov     di,offset our_type
  1085.     mov     cx,RxPktLen
  1086.  
  1087.     call    recv_find               ;request a Rx buffer to store Rx data
  1088.  
  1089.     mov     ax,es                   ;is this pointer null?
  1090.     or      ax,di
  1091.     jnz     find_buffer1
  1092.     jmp     CheckTx                 ;yes - just free the frame.
  1093. find_buffer1:
  1094.     push    es
  1095.     push    di                   ;remember where the buffer pointer is.
  1096.     assume  ds:nothing
  1097.     mov     bx,RxStartAdd
  1098.     mov     cx,RW_ADR
  1099.     loadport
  1100.     setport DAT
  1101.     write_sub_slow    bl
  1102.     call    delay
  1103.     write_sub_slow    bh
  1104.     call    delay
  1105.  
  1106.     cld
  1107.     mov     bp,RxPktLen             ;CX = the byte count of Rx Packet
  1108.     setport STAT
  1109.     mov     cx,READ
  1110.     mov     ah,ch
  1111.     xor     ah,08h
  1112. read_mem1:
  1113.     dec     dx
  1114.     mov     al,ch
  1115.     out     dx,al
  1116.     call    delay
  1117.  
  1118.     inc     dx
  1119.     in      al,dx
  1120.     mov     bl,al
  1121.     dec     dx
  1122.     mov     al,ah
  1123.     out     dx,al
  1124.     call    delay
  1125.  
  1126.     inc     dx
  1127.     in      al,dx
  1128.     shr     bl,cl
  1129.     and     al,0f0h
  1130.     or      al,bl
  1131.     stosb
  1132.     dec     bp
  1133.     jnz     read_mem1
  1134.     jmp     RxCopy_CheckTx
  1135.  
  1136.  
  1137. recv2:
  1138.     assume  ds:code
  1139.     mov     NICstatus,al            ; save NIC status
  1140.     loadport
  1141.     setport DAT
  1142.     test    al,GOOD                 ; Is Rx generating interrupt ?
  1143.     mov     al,NUL_CMD
  1144.     out     dx,al
  1145.     jnz     Rx_Good_Pkt2             ; Yes, take care of this situation.
  1146.     mov     al,NICstatus
  1147.     test    al,RXBUSY
  1148.     jz      Enable_Rx2
  1149.     jmp     CheckTx                 ; No, go to check Tx.
  1150.  
  1151. Enable_Rx2:
  1152. ;change Rx page & enable NIC to Rx
  1153.     mov     bl,Mode_RxPg
  1154.     mov     cx,COMMAND
  1155.     setport DAT
  1156.     write_sub_delay    bl
  1157.     call    delay
  1158.     or      bl,RXEN
  1159.   if 0
  1160.     write_sub_delay    bl
  1161.   else
  1162.     mov     al,bl
  1163.     shl     al,cl
  1164.     or      al,ch
  1165.     xor     al,08h
  1166.     out     dx,al
  1167.     call    delay
  1168.  
  1169.     xor     al,08h
  1170.     out     dx,al
  1171.     call    delay
  1172.  
  1173.     mov     al,bl
  1174.     and     al,0f0h
  1175.     or      al,ch
  1176.     xor     al,08h
  1177.     out     dx,al
  1178.   endif
  1179.     jmp     CheckTx
  1180.  
  1181. Rx_Good_Pkt2:
  1182. ;Put it on the receive queue
  1183.     mov     cx,RX_LEN               ; read Rx Packet Length
  1184.     loadport
  1185.  
  1186.     read_sub_delay    bl, 1
  1187.     read_sub_delay    bh, 0
  1188.  
  1189.     sub     bx,4                    ;subtrate 4 CRC Byte Count
  1190.     mov     RxPktLen,bx             ;save Rx Packet Length
  1191.  
  1192. ;change Rx page & enable NIC to Rx
  1193.     xor     Mode_RxPg,10h
  1194.     mov     bl,Mode_RxPg
  1195.     mov     cx,COMMAND
  1196.     setport DAT
  1197.     write_sub_delay    bl
  1198.     call    delay
  1199.     or      bl,RXEN
  1200.     write_sub_delay    bl
  1201.     call    delay
  1202.  
  1203.     xor     bx,bx
  1204.     mov     bh,CurRxPage            ;BL = Current Rx Page
  1205.     xor     CurRxPage,10h           ;change to next page for Rx
  1206.     shr     bx,1                    ;shift BX to real memory address
  1207.     mov     RxStartAdd,bx           ;save just Rx Packet Start Address
  1208.  
  1209.     add     bx,EADDR_LEN+EADDR_LEN  ;seek to the TYPE word
  1210.     mov     cx,RW_ADR
  1211.     write_sub_delay    bl
  1212.     call    delay
  1213.     write_sub_delay    bh
  1214.     call    delay
  1215.  
  1216.     mov     cx,READ                 ;read the TYPE word
  1217.  
  1218.     read_sub_delay    bl, 1
  1219.     read_sub_delay    bh, 0
  1220.     mov     our_type,bx             ;save the TYPE word
  1221.  
  1222.     mov     ax,ds
  1223.     mov     es,ax
  1224.     mov     di,offset our_type
  1225.     mov     cx,RxPktLen
  1226.  
  1227.     call    recv_find               ;request a Rx buffer to store Rx data
  1228.  
  1229.     mov     ax,es                   ;is this pointer null?
  1230.     or      ax,di
  1231.     jnz     find_buffer2
  1232.     jmp     CheckTx                 ;yes - just free the frame.
  1233. find_buffer2:
  1234.     push    es
  1235.     push    di                   ;remember where the buffer pointer is.
  1236.     assume  ds:nothing
  1237.     mov     bx,RxStartAdd
  1238.     mov     cx,RW_ADR
  1239.     loadport
  1240.     setport DAT
  1241.     write_sub_delay    bl
  1242.     call    delay
  1243.     write_sub_delay    bh
  1244.     call    delay
  1245.  
  1246.     cld
  1247.     mov     bp,RxPktLen             ;CX = the byte count of Rx Packet
  1248.     setport STAT
  1249.     mov     cx,READ
  1250.     mov     ah,ch
  1251.     xor     ah,08h
  1252. read_mem2:
  1253.     dec     dx
  1254.     mov     al,ch
  1255.     out     dx,al
  1256.     call    delay
  1257.  
  1258.     inc     dx
  1259.     in      al,dx
  1260.     mov     bl,al
  1261.     dec     dx
  1262.     mov     al,ah
  1263.     out     dx,al
  1264.     call    delay
  1265.  
  1266.     inc     dx
  1267.     in      al,dx
  1268.     shr     bl,cl
  1269.     and     al,0f0h
  1270.     or      al,bl
  1271.     stosb
  1272.     dec     bp
  1273.     jnz     read_mem2
  1274.     jmp     RxCopy_CheckTx
  1275.  
  1276.  
  1277.     public    recv_exiting
  1278. recv_exiting:
  1279. ;called from the recv isr after interrupts have been acknowledged.
  1280. ;Only ds and ax have been saved.
  1281.     assume    ds:nothing
  1282.     ret
  1283.  
  1284.  
  1285.     public  end_resident
  1286. end_resident    label   byte
  1287. ;any code after this will not be kept after initialization.
  1288.  
  1289.     public  usage_msg
  1290. usage_msg       db      "usage: DE600PD <packet_int_no>",CR,LF,'$'
  1291.  
  1292.     public  copyright_msg
  1293. copyright_msg   db      "Packet driver for the D-Link DE-600, "
  1294.             db      "version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,CR,LF,'$'
  1295.             db      "Portions Copyright 1988, Robert C. Clements, K1BC"
  1296.             db      CR,LF,'$'
  1297.  
  1298. CableErr        db      "Bad cable connection.",07,CR,LF,'$'
  1299. mem_error_msg   db      "Adapter memory buffer failure, or bad printer "
  1300.             db      "port connection.",07,CR,LF,'$'
  1301. irq_error_msg   db      "IRQ unavailable, please check other hardware in "
  1302.             db      "computer.",07,CR,LF,'$'
  1303. no_NIC_err      db      "Adapter not found, or AC adapter power is off.",07,CR,LF,'$'
  1304.  
  1305.     extrn   set_recv_isr: near
  1306.  
  1307. ;enter with si -> argument string, di -> word to store.
  1308. ;if there is no number, don't change the number.
  1309.     extrn    get_number: near
  1310.  
  1311. ;enter with dx -> name of word, di -> dword to print.
  1312.     extrn    print_number: near
  1313.  
  1314.     assume  ds:code
  1315.     public  parse_args
  1316. parse_args:
  1317.     ret
  1318.  
  1319.  
  1320.     public  print_parameters
  1321. print_parameters:
  1322.     ret
  1323.  
  1324. cable_err:
  1325.     mov     dx,offset CableErr
  1326.     jmp     short show_msg
  1327. IRQ_error:
  1328.     mov     dx,offset irq_error_msg
  1329.     jmp     short show_msg
  1330. no_our_NIC:
  1331.     mov     dx,offset no_NIC_err
  1332.     jmp     short show_msg
  1333. mem_error:
  1334.     mov     dx,offset mem_error_msg
  1335. show_msg:
  1336.     mov     ah,9
  1337.     int     21h
  1338.     stc
  1339.     ret
  1340.  
  1341.     public  etopen
  1342. etopen:
  1343. ;  Initialize the Ethernet board.
  1344.     call    check_PS2
  1345.  
  1346.     xor     ax,ax
  1347.     mov     es,ax
  1348.     mov     si,PRNTABADD-2          ; point to printer table at low memory
  1349. next_prn_port:
  1350.     add     si,2
  1351.     mov     bx,es:[si]              ; get LPTx's I/O Base
  1352.     or      bx,bx                   ; Does LPTx really exist ?
  1353.     jz      Chk_out_of_range
  1354.     mov     io_addr,bx              ; save the I/O Base number
  1355.     mov     printer,si              ; memorize it's LPTx now
  1356.     call    Check_DE600             ; Yes, BX = I/O Base, then check.
  1357.     jnc     IO_good                 ; If carry flag is clear, so go to
  1358.     mov     al,NML_PRN
  1359.     call    CMD_sub
  1360. Chk_out_of_range:
  1361.     cmp     si,PRNTABADD+6          ; We still miss our card from LPT1 to
  1362.     jb      next_prn_port
  1363.     jmp     short no_our_NIC        ; We still miss our card from LPT1 to
  1364.                                     ; LPT4. We give it up.
  1365. IO_good:
  1366. ; Copy our Ethernet address from PROM into DE600.
  1367.     push    ds
  1368.     pop     es
  1369.     mov     di,offset our_address
  1370.     mov     cx,RW_ADR
  1371.     xor     bl,bl
  1372.     call    Write_sub
  1373.     or      bl,HA13
  1374.     call    Write_sub
  1375.  
  1376.     cld
  1377.     mov     bp,EADDR_LEN
  1378.     mov     cx,READ
  1379. get_our_address:
  1380.     call    Read_sub
  1381.     mov     al,bl
  1382.     stosb
  1383.     dec     bp
  1384.     jnz     get_our_address
  1385.  
  1386.     mov     si,offset our_address    ;make sure it's got the right magic
  1387.     cmp     word ptr es:[si],0de00h    ;  number.
  1388.     jne     no_our_NIC
  1389.     cmp     byte ptr es:[si+2],15h
  1390.     jne     no_our_NIC
  1391.  
  1392.     mov     word ptr es:[si],8000h    ;now modify it to the address assigned
  1393.     mov     byte ptr es:[si+2],0c8h    ;  by Xerox.
  1394.     and     byte ptr es:[si+3],0fh
  1395.     or      byte ptr es:[si+3],070h
  1396.  
  1397.     mov     cx,EADDR_LEN
  1398.     call    set_address
  1399.  
  1400. ; Check DE600's IRQ enviroment
  1401.     call    Check_IRQ
  1402.     cmp     bx,1
  1403.     je      cable_OK
  1404.     jmp     cable_err
  1405.  
  1406. cable_OK:
  1407.     mov     bx,offset delay
  1408.     mov     byte ptr [bx],0c3h     ;  ret
  1409.  
  1410. ; test 8 KBytes memory
  1411. ;********** write mode 1 *************
  1412.     mov     cx,700h
  1413.     mov     al,PAGE3
  1414.     call    Write_LoopBack_Data
  1415.     xor     bx,bx
  1416.     mov     si,bx
  1417. write_next_page:
  1418.     call    Tx_Data
  1419.     push    bx
  1420.     mov     cx,RW_ADR
  1421.     loadport
  1422.     setport DAT
  1423.     write_sub_fast    bl
  1424.     write_sub_fast    bh
  1425.  
  1426.     mov     bx,si
  1427.     mov     bp,800h
  1428.     mov     cx,WRITE
  1429.     mov     ah,ch
  1430.     xor     ah,08h
  1431. wr_this_page:
  1432.     mov     al,bl
  1433.     shl     al,cl
  1434.     or      al,ch
  1435.     out     dx,al
  1436.     mov     al,bl
  1437.     and     al,0f0h
  1438.     or      al,ah
  1439.     out     dx,al
  1440.     inc     bl
  1441.     dec     bp
  1442.     jnz     wr_this_page
  1443.     inc     si
  1444.     pop     bx
  1445.     add     bx,800h
  1446.     cmp     bx,1800h
  1447.     ja      read_memory
  1448.     jmp     short write_next_page
  1449.  
  1450. ;************ read mode 1 ************
  1451. read_memory:
  1452.     loadport
  1453.     setport DAT
  1454.     xor     bx,bx
  1455.     mov     si,bx
  1456. read_next_page:
  1457.     push    bx
  1458.     mov     cx,RW_ADR
  1459.     write_sub_fast    bl
  1460.     write_sub_fast    bh
  1461.  
  1462.     mov     bx,si
  1463.     mov     bp,800h
  1464.     mov     cx,READ
  1465.     mov     ah,ch
  1466.     xor     ah,08h
  1467. rd_this_page:
  1468.     mov     al,ch
  1469.     out     dx,al
  1470.     pause
  1471.     inc     dx
  1472.     in      al,dx
  1473.     mov     bh,al
  1474.     dec     dx
  1475.     mov     al,ah
  1476.     out     dx,al
  1477.     pause
  1478.     inc     dx
  1479.     in      al,dx
  1480.     shr     bh,cl
  1481.     and     al,0f0h
  1482.     or      bh,al
  1483.     cmp     bh,bl
  1484.     jne     memory_test
  1485.     dec     dx
  1486.     inc     bl
  1487.     dec     bp
  1488.     jnz     rd_this_page
  1489.     inc     si
  1490.     pop     bx
  1491.     add     bx,800h
  1492.     cmp     bx,1800h
  1493.     ja      mem_is_OK
  1494.     push    si
  1495.     push    bx
  1496.     mov     cx,700h
  1497.     mov     al,PAGE0
  1498.     call    Write_LoopBack_Data
  1499.     call    Tx_Data
  1500.     pop     bx
  1501.     pop     si
  1502.     jmp     short read_next_page
  1503. mem_is_OK:
  1504.     jmp     mem_OK
  1505.  
  1506. ;************ write mode 2 ***************
  1507. memory_test:
  1508.     pop     ax
  1509. memory_test1:
  1510.     mov     cx,700h
  1511.     mov     al,PAGE3
  1512.     call    Write_LoopBack_Data
  1513.     xor     bx,bx
  1514.     mov     si,bx
  1515. write_next_page1:
  1516.     call    Tx_Data
  1517.     push    bx
  1518.     mov     cx,RW_ADR
  1519.     loadport
  1520.     setport DAT
  1521.     write_sub_slow    bl
  1522.     call    delay
  1523.     write_sub_slow    bh
  1524.     call    delay
  1525.  
  1526.     mov     bx,si
  1527.     mov     bp,800h
  1528.     mov     cx,WRITE
  1529.     mov     ah,ch
  1530.     xor     ah,08h
  1531. wr_this_page1:
  1532.     mov     al,bl
  1533.     shl     al,cl
  1534.     or      al,ch
  1535.     out     dx,al
  1536.     call    delay
  1537.  
  1538.     mov     al,bl
  1539.     and     al,0f0h
  1540.     or      al,ah
  1541.     out     dx,al
  1542.     call    delay
  1543.     inc     bl
  1544.     dec     bp
  1545.     jnz     wr_this_page1
  1546.     inc     si
  1547.     pop     bx
  1548.     add     bx,800h
  1549.     cmp     bx,1800h
  1550.     ja      read_memory1
  1551.     jmp     short write_next_page1
  1552.  
  1553. ;************* read mode 2 **************
  1554. read_memory1:
  1555.     loadport
  1556.     setport DAT
  1557.     xor     bx,bx
  1558.     mov     si,bx
  1559. read_next_page1:
  1560.     push    bx
  1561.     mov     cx,RW_ADR
  1562.     write_sub_slow    bl
  1563.     call    delay
  1564.     write_sub_slow    bh
  1565.     call    delay
  1566.  
  1567.     mov     bx,si
  1568.     mov     bp,800h
  1569.     mov     cx,READ
  1570.     mov     ah,ch
  1571.     xor     ah,08h
  1572. rd_this_page1:
  1573.     mov     al,ch
  1574.     out     dx,al
  1575.     call    delay
  1576.  
  1577.     inc     dx
  1578.     in      al,dx
  1579.     mov     bh,al
  1580.     dec     dx
  1581.     mov     al,ah
  1582.     out     dx,al
  1583.     call    delay
  1584.  
  1585.     inc     dx
  1586.     in      al,dx
  1587.     shr     bh,cl
  1588.     and     al,0f0h
  1589.     or      bh,al
  1590.     cmp     bh,bl
  1591.     jne     memory_test2
  1592.     dec     dx
  1593.     inc     bl
  1594.     dec     bp
  1595.     jnz     rd_this_page1
  1596.     inc     si
  1597.     pop     bx
  1598.     add     bx,800h
  1599.     cmp     bx,1800h
  1600.     ja      mem_is_OK1
  1601.     push    si
  1602.     push    bx
  1603.     mov     cx,700h
  1604.     mov     al,PAGE0
  1605.     call    Write_LoopBack_Data
  1606.     call    Tx_Data
  1607.     pop     bx
  1608.     pop     si
  1609.     jmp     read_next_page1
  1610. mem_is_OK1:
  1611.     jmp     mem_OK1
  1612.  
  1613. ;************* write mode 3 ***************
  1614. memory_test2:
  1615.     pop     ax
  1616. memory_test3:
  1617.     mov     cx,700h
  1618.     mov     al,PAGE3
  1619.     call    Write_LoopBack_Data
  1620.     xor     bx,bx
  1621.     mov     si,bx
  1622. write_next_page3:
  1623.     call    Tx_Data
  1624.     push    bx
  1625.     mov     cx,RW_ADR
  1626.     loadport
  1627.     setport DAT
  1628.     write_sub_delay    bl
  1629.     call    delay
  1630.     write_sub_delay    bh
  1631.     call    delay
  1632.  
  1633.     mov     bx,si
  1634.     mov     bp,800h
  1635.     mov     cx,WRITE
  1636. wr_this_page3:
  1637.     mov     al,bl
  1638.     shl     al,cl
  1639.     or      al,ch
  1640.     xor     al,08h
  1641.     out     dx,al
  1642.     call    delay
  1643.  
  1644.     xor     al,08h
  1645.     out     dx,al
  1646.     call    delay
  1647.  
  1648.     mov     al,bl
  1649.     and     al,0f0h
  1650.     or      al,ch
  1651.     out     dx,al
  1652.     call    delay
  1653.  
  1654.     xor     al,08h
  1655.     out     dx,al
  1656.     call    delay
  1657.     inc     bl
  1658.     dec     bp
  1659.     jnz     wr_this_page3
  1660.     inc     si
  1661.     pop     bx
  1662.     add     bx,800h
  1663.     cmp     bx,1800h
  1664.     ja      read_memory3
  1665.     jmp     write_next_page3
  1666.  
  1667. ;************* read mode 3 ***************
  1668. read_memory3:
  1669.     loadport
  1670.     setport DAT
  1671.     xor     bx,bx
  1672.     mov     si,bx
  1673. read_next_page3:
  1674.     push    bx
  1675.     mov     cx,RW_ADR
  1676.     write_sub_delay    bl
  1677.     call    delay
  1678.     write_sub_delay    bh
  1679.  
  1680.     call    delay
  1681.  
  1682.     mov     bx,si
  1683.     mov     bp,800h
  1684.     mov     cx,READ
  1685.     mov     ah,ch
  1686.     xor     ah,08h
  1687.  
  1688.     mov     al,ch
  1689.     xor     al,08h
  1690.     out     dx,al
  1691.     call    delay
  1692. rd_this_page3:
  1693.     mov     al,ch
  1694.     out     dx,al
  1695.     call    delay
  1696.  
  1697.     setport STAT
  1698.     in      al,dx
  1699.     mov     bh,al
  1700.     setport DAT
  1701.     mov     al,ah
  1702.     out     dx,al
  1703.     call    delay
  1704.  
  1705.     setport STAT
  1706.     in      al,dx
  1707.     shr     bh,cl
  1708.     and     al,0f0h
  1709.     or      bh,al
  1710.     cmp     bh,bl
  1711.     jne     mem_err
  1712.     setport    DAT
  1713.     inc     bl
  1714.     dec     bp
  1715.     jnz     rd_this_page3
  1716.     inc     si
  1717.     pop     bx
  1718.     add     bx,800h
  1719.     cmp     bx,1800h
  1720.     ja      mem_OK2
  1721.     push    si
  1722.     push    bx
  1723.     mov     cx,700h
  1724.     mov     al,PAGE0
  1725.     call    Write_LoopBack_Data
  1726.     call    Tx_Data
  1727.     pop     bx
  1728.     pop     si
  1729.     jmp     read_next_page3
  1730.  
  1731. pointer         dw      0
  1732.  
  1733. mem_err:
  1734.     pop     bx
  1735.     cmp     pointer,9        ;too slow?  Must not be working.
  1736.     ja      mem_real_err
  1737.     mov     bx,offset delay        ;append another NOP and RET in.
  1738.     add     bx,pointer
  1739.     mov     [bx],0c390h
  1740.     inc     pointer            ;slow it down a little more and try
  1741.     jmp     memory_test3        ;  again.
  1742. mem_real_err:
  1743.     jmp     mem_error
  1744.  
  1745. change_routine:
  1746.     mov     ax,offset recv1
  1747.     mov     recv_pointer,ax
  1748.     mov     ax,offset send_pkt1
  1749.     mov     send_pkt_pointer,ax
  1750.     ret
  1751.  
  1752. change_routine2:
  1753.     mov     ax,offset recv2
  1754.     mov     recv_pointer,ax
  1755.     mov     ax,offset send_pkt2
  1756.     mov     send_pkt_pointer,ax
  1757.     ret
  1758.  
  1759. ;********** memory test passed ****************
  1760. mem_OK1:
  1761.     call    change_routine
  1762.     jmp     short mem_OK
  1763. mem_OK2:
  1764.     call    change_routine2
  1765. mem_OK:
  1766.     call    speed_test
  1767.  
  1768.     push    es
  1769.     xor     ax,ax
  1770.     mov     es,ax
  1771.     mov     si,printer
  1772.     mov     word ptr es:[si],ax     ; Zero-out Printer Port
  1773.     pop     es
  1774.  
  1775. ; Initialize Rx buffer pointer, and start receive
  1776.     mov     bl,Mode
  1777.     or      bl,IRQinverse
  1778.     or      bl,CurRXPage
  1779.     mov     Mode_RxPg,bl
  1780.     mov     cx,COMMAND
  1781.     call    Write_sub
  1782.     or      bl,RXEN
  1783.     call    Write_sub
  1784.  
  1785. ; Put our Receive routine in interrupt chain
  1786.     call    set_recv_isr
  1787.  
  1788. ; We didn't need to enable the receive & transmit interrupts, they were
  1789. ; set by hardware already. (accept GOOD, SUC & T16 to generate interrupt)
  1790.  
  1791. ; Enable Printer Adapter IRQ line
  1792.     mov     al,SLT_PRN
  1793.     call    CMD_sub
  1794.  
  1795.     mov     dx,offset end_resident
  1796.     clc
  1797.     ret
  1798.  
  1799.  
  1800. ;*********** sub-routine *************
  1801. ; Check DE-600 routine
  1802. Check_DE600:
  1803.     mov     al,SLT_NIC
  1804.     call    CMD_sub
  1805.     call    delay
  1806.  
  1807.     loadport
  1808.     setport DAT
  1809.     mov     al,NUL_CMD
  1810.     out     dx,al
  1811.     call    delay
  1812.  
  1813.     mov     bl,RESET
  1814.     mov     cx,COMMAND
  1815.     call    Write_sub
  1816.     call    delay
  1817.     mov     bl,STOP_RESET
  1818.     call    Write_sub
  1819.     call    delay
  1820.  
  1821.     mov     cx,STATUS
  1822.     call    Read_sub
  1823.     test    bl,0f0h
  1824.     jz      Check_OK
  1825.     stc
  1826.     ret
  1827. Check_OK:
  1828.     clc
  1829.     ret
  1830.  
  1831. OldIRQ5 dd      0
  1832. OldIRQ7 dd      0
  1833.  
  1834. NewIRQ5:
  1835.     push    ax
  1836.     push    bx
  1837.     push    cx
  1838.     push    dx
  1839.     push    ds
  1840.     mov     al,20h
  1841.     out     20h,al
  1842.     mov     ax,cs
  1843.     mov     ds,ax
  1844.     cmp     LB,0
  1845.     jz      DisCare_IRQ5
  1846.     mov     bh,5
  1847.     call    Clear_int
  1848. DisCare_IRQ5:
  1849.     pop     ds
  1850.     pop     dx
  1851.     pop     cx
  1852.     pop     bx
  1853.     pop     ax
  1854.     iret
  1855.  
  1856. NewIRQ7:
  1857.     push    ax
  1858.     push    bx
  1859.     push    cx
  1860.     push    dx
  1861.     push    ds
  1862.     mov     al,20h
  1863.     out     20h,al
  1864.     mov     ax,cs
  1865.     mov     ds,ax
  1866.     cmp     LB,0
  1867.     jz      DisCare_IRQ7
  1868.     mov     bh,7
  1869.     call    Clear_int
  1870. DisCare_IRQ7:
  1871.     pop     ds
  1872.     pop     dx
  1873.     pop     cx
  1874.     pop     bx
  1875.     pop     ax
  1876.     iret
  1877.  
  1878. replace_IRQ5_7:
  1879.     xor     cx,cx
  1880.     mov     es,cx
  1881.     mov     di,034h
  1882.     mov     ax,es:[di]                      ;save old interrupt vector
  1883.     mov     word ptr OldIRQ5,ax
  1884.     mov     ax,es:[di]+2
  1885.     mov     word ptr OldIRQ5+2,ax
  1886.     mov     ax,offset NewIRQ5
  1887.     stosw
  1888.     mov     ax,cs
  1889.     stosw
  1890.  
  1891.     mov     di,03ch
  1892.     mov     ax,es:[di]                      ;save old interrupt vector
  1893.     mov     word ptr OldIRQ7,ax
  1894.     mov     ax,es:[di]+2
  1895.     mov     word ptr OldIRQ7+2,ax
  1896.     mov     ax,offset NewIRQ7
  1897.     stosw
  1898.     mov     ax,cs
  1899.     stosw
  1900.  
  1901.     in      al,21h
  1902.     mov     intmask,al
  1903.     pause
  1904.     pause
  1905.     and     al,5fh
  1906.     out     21h,al
  1907.     ret
  1908.  
  1909. intmask         db      0
  1910. INT_come        db      0
  1911. T16_flag        db      0
  1912. LB              db      0
  1913.  
  1914. restore_IRQ5_7:
  1915.     xor     cx,cx
  1916.     mov     es,cx
  1917.     mov     di,034h
  1918.     mov     ax,word ptr OldIRQ5
  1919.     mov     es:[di],ax                      ;save old interrupt vector
  1920.     mov     ax,word ptr OldIRQ5+2
  1921.     mov     es:[di]+2,ax
  1922.  
  1923.     mov     di,03ch
  1924.     mov     ax,word ptr OldIRQ7
  1925.     mov     es:[di],ax                      ;save old interrupt vector
  1926.     mov     ax,word ptr OldIRQ7+2
  1927.     mov     es:[di]+2,ax
  1928.  
  1929.     mov     al,intmask
  1930.     out     21h,al
  1931.     ret
  1932.  
  1933. Write_LoopBack_Data:
  1934.     mov     si,offset our_address
  1935.     mov     di,si
  1936. ;set Tx Pointer for moving packet
  1937.     mov     bx,BFRSIZ
  1938.     sub     bx,cx           ;CX= Packet Length
  1939.     or      bh,al           ;AL= Page Number
  1940.     mov     TxStartAdd,bx   ;BX= the pointer to TX
  1941.     mov     cx,RW_ADR       ;write memory address
  1942.     call    Write_sub
  1943.     mov     bl,bh
  1944.     call    Write_sub
  1945.     cld
  1946.     loadport
  1947.     setport DAT
  1948.     mov     bp,12
  1949.     mov     cx,WRITE
  1950. write_our_node_ID:
  1951.     lodsb
  1952.     mov     bl,al
  1953.     call    Write_sub
  1954.     cmp     bp,7
  1955.     jne     not_second_ID
  1956.     mov     si,di
  1957. not_second_ID:
  1958.     dec     bp
  1959.     jnz     write_our_node_ID
  1960.     ret
  1961.  
  1962. Tx_Data:
  1963. ;Check TXIDLE, if high then wait for previous Tx end, if low then Tx it
  1964.     mov     cx,800h        ; Avoid infinite loop
  1965.     loadport
  1966.     setport STAT
  1967. wait_Txidle0:
  1968.     in      al,dx
  1969.     test    al,TXBUSY       ; Is the previous Tx successful ?
  1970.     jz      Tx_next0        ; Yes, TXBUSY is low. Then could Tx next packet.
  1971.     loop    wait_Txidle0
  1972. Tx_next0:
  1973. ;set Tx Pointer at beginning of packet
  1974.     push    bx
  1975.     mov     cx,TX_ADR
  1976.     mov     bx,TxStartAdd
  1977.     call    Write_sub
  1978.     mov     bl,bh
  1979.     call    Write_sub
  1980. ;Enable interrupt and start Tx
  1981.     mov     cx,COMMAND
  1982.     mov     bl,RX_NONE
  1983.     call    Write_sub
  1984.     or      bl,TXEN
  1985.     call    Write_sub
  1986.     pop     bx
  1987.     ret
  1988.  
  1989. LoopBack_Tx:
  1990. ;set Tx Pointer at beginning of packet
  1991.     mov     bx,TxStartAdd
  1992.     mov     cx,TX_ADR
  1993.     call    Write_sub
  1994.     mov     bl,bh
  1995.     call    Write_sub
  1996. ;Enable interrupt and start Tx
  1997.     mov     bl,RX_BP
  1998.     or      bl,IRQinverse
  1999.     mov     cx,COMMAND
  2000.     call    Write_sub
  2001.     or      bl,LOOPBACK
  2002.     call    Write_sub
  2003.  
  2004.     mov     LB,1
  2005.     mov     al,SLT_PRN
  2006.     call    CMD_sub
  2007.  
  2008.     xor     bx,bx
  2009.     mov     cx,8000h
  2010. wait_int:
  2011.     cmp     INT_come,0
  2012.     jz      have_T16
  2013.     mov     bx,1
  2014.     jmp     short exit_LoopBack
  2015. have_T16:
  2016.     cmp     T16_flag,0
  2017.     jz      still_wait
  2018.     mov     bx,-1
  2019.     jmp     short exit_LoopBack
  2020. still_wait:
  2021.     loop    wait_int
  2022.  
  2023. exit_LoopBack:
  2024.     mov     LB,0
  2025.     mov     al,SLT_NIC
  2026.     call    CMD_sub
  2027.  
  2028.     push    bx
  2029.     mov     cx,STATUS
  2030.     call    Read_sub
  2031.     pop     bx
  2032.     ret
  2033.  
  2034. Clear_int:
  2035.     mov     al,SLT_NIC
  2036.     call    CMD_sub
  2037.     pause
  2038.     mov     cx,STATUS
  2039.     call    Read_sub
  2040.  
  2041.     mov     T16_flag,0
  2042.     test    bl,GOOD         ; Is Rx generating interrupt ?
  2043.     jz      chk_T16
  2044.     mov     INT_come,1
  2045.     mov     int_no,bh
  2046.     jmp     short exit_Clear_int
  2047. chk_T16:
  2048.     test    bl,T16          ; Is pending a Tx Packet ?
  2049.     jz      exit_Clear_int
  2050.     mov     T16_flag,1
  2051. exit_Clear_int:
  2052.     ret
  2053.  
  2054. Check_IRQ:
  2055.     call    replace_IRQ5_7
  2056.     sti
  2057.     mov     cx,RUNT
  2058.     mov     al,PAGE0
  2059.     call    Write_LoopBack_Data
  2060.     call    LoopBack_Tx     ; check IRQ= 7 or 5 but IRQ not inverse
  2061.     cmp     bx,0
  2062.     jnz     IRQ_OK
  2063.  
  2064. ;Check TXIDLE, if high then wait for previous Tx end, if low then Tx it
  2065.     mov     cx,800h        ; Avoid infinite loop
  2066.     loadport
  2067.     setport STAT
  2068. wait_Txidle:
  2069.     in      al,dx
  2070.     test    al,TXBUSY       ; Is the previous Tx successful ?
  2071.     jz      Tx_next         ; Yes, TXBUSY is low. Then could Tx next packet.
  2072.     loop    wait_Txidle
  2073. Tx_next:
  2074.     mov     IRQinverse,40h  ; check IRQ= 7 or 5 but IRQ inverse
  2075.     mov     PS2,0
  2076.     call    LoopBack_Tx
  2077. IRQ_OK:
  2078.     cli
  2079.     call    restore_IRQ5_7
  2080.     ret
  2081.  
  2082. check_PS2:
  2083.     mov     ax,0c400h
  2084.     int     15h
  2085.     jc      not_PS2
  2086.     mov     PS2,1
  2087. not_PS2:
  2088.     ret
  2089.  
  2090. speed_test:
  2091.     xor     ax,ax
  2092.     mov     es,ax
  2093.     mov     si,20h
  2094.     mov     ax, es:[si]
  2095.     mov     cs:old_int8, ax
  2096.     mov     ax, es:[si+2]
  2097.     mov     cs:old_int8[2], ax
  2098.     cli
  2099.     mov     ax,offset new_int8
  2100.     mov     es:[si],ax
  2101.     mov     es:[si+2],cs
  2102.     sti
  2103.  
  2104. next_test1:
  2105.     mov     ticks_start,0
  2106. next_test:
  2107.     cmp     ticks_start,0
  2108.     jz      next_test
  2109.     mov     ticks,0
  2110.     xor     bx,bx
  2111. loop_again:
  2112.     mov     cx,6
  2113.     loop    $
  2114.     cmp     ticks,2
  2115.     jae     End_count
  2116.     inc     bx
  2117.     jmp     short loop_again
  2118.  
  2119. End_count:
  2120.     cli
  2121.     xor     ax,ax
  2122.     mov     es,ax
  2123.     mov     si,20h
  2124.     mov     ax,old_int8
  2125.     mov     es:[si],ax
  2126.     mov     ax,old_int8[2]
  2127.     mov     es:[si+2],ax
  2128.     sti
  2129.     cmp     bx,0a000h
  2130.     jb      low_speed
  2131.     mov     ax,offset recv1         ; special for high speed EISA
  2132.     mov     recv_pointer,ax
  2133. low_speed:
  2134.     ret
  2135.  
  2136. ticks_start     db      0
  2137. ticks           db      0
  2138. old_int8        dw      ?
  2139.             dw      ?
  2140. new_int8:
  2141.     inc     ticks
  2142.     inc     ticks_start
  2143.     jmp     dword ptr cs:old_int8
  2144.  
  2145.     code    ends
  2146.     end
  2147.